package plgbase

import (
	"dgo/goutils/utils"
	"fmt"
	"gitee.com/ymofen/supervalue"
)

type PlgBase struct {
	RealPlg     interface{} // 创建时赋值
	PlugId      string      // 第一次修改后不可以修改
	PlugDNA     uint32      // 外部不可以
	ReleaseFlag int         // 外部不可以 1:表示该插件已经释放, 插件一旦释放不会被再次激活(只会创建新的插件)

	closeEventlist []func()

	InputEx        *InnerEx
	StatusOutputEx *InnerOutput
	StatusEx       *InnerEx
	OutputEx       *InnerEx
}

func (this *PlgBase) String() string {
	return fmt.Sprintf("%s", this.PlugId)
}

func (this *PlgBase) SetPlugID(val string) {
	this.PlugId = val
	this.CheckDNA()
}

func (this *PlgBase) GetPlugID() string {
	return this.PlugId
}

func (this *PlgBase) IsRelease() bool {
	return this.ReleaseFlag == 1
}

func (this *PlgBase) Release() {
	this.ReleaseFlag = 1
	if this.StatusOutputEx != nil {
		this.StatusOutputEx.Release()
		this.StatusOutputEx = nil
	}

	if this.InputEx != nil {
		this.InputEx.Release()
		this.InputEx = nil
	}

	if this.OutputEx != nil {
		this.OutputEx.Release()
		this.OutputEx = nil
	}
}

func (this *PlgBase) AddCloseFunc(fn func()) {
	this.closeEventlist = append(this.closeEventlist, fn)
}

func (this *PlgBase) Close() error {
	for i := 0; i < len(this.closeEventlist); i++ {
		this.closeEventlist[i]()
	}
	this.Release()
	return nil
}

func (this *PlgBase) CheckDNA() uint32 {
	if this.PlugDNA == 0 {
		this.PlugDNA = utils.NewObjectDNA()
	}
	return this.PlugDNA
}

func (this *PlgBase) ReloadInputConf(conf *wrapper.SuperValue, onInput utils.SubscribeCallback) (err error) {
	if this.RealPlg == nil {
		this.RealPlg = this
	}
	if this.InputEx == nil {
		this.InputEx = NewInnerEx()
		this.InputEx.ConfigOwnerPlug(this.RealPlg)
	}

	if conf == nil {
		return nil
	}

	this.InputEx.ReloadConf(conf)
	this.InputEx.SubscribeFromConf(conf, onInput)
	return nil
}

func (this *PlgBase) ReloadInputConf0(conf *wrapper.SuperValue) (err error) {
	if this.RealPlg == nil {
		this.RealPlg = this
	}
	if this.InputEx == nil {
		this.InputEx = NewInnerEx()
		this.InputEx.ConfigOwnerPlug(this.RealPlg)
	}

	if conf == nil {
		return nil
	}

	return this.InputEx.ReloadConf(conf)
}

func (this *PlgBase) ReloadStatusOConf(conf *wrapper.SuperValue,
	status_fn func(), status_fn_start func(), status_fn_shutdown func()) (err error) {
	if conf == nil {
		return
	}
	if this.StatusOutputEx == nil {
		this.StatusOutputEx = NewInnerOutput()
		this.StatusOutputEx.ConfigOwnerPlug(this.RealPlg)
	}

	return this.StatusOutputEx.ReloadConf(conf, status_fn, status_fn_start, status_fn_shutdown)
}

func (this *PlgBase) ReloadOutputConf(conf *wrapper.SuperValue) (err error) {
	if this.OutputEx == nil {
		this.OutputEx = NewInnerEx()
	}

	return this.OutputEx.ReloadConf(conf)
}

func (this *PlgBase) ReloadStatusConf(conf *wrapper.SuperValue) (err error) {
	if this.StatusEx == nil {
		this.StatusEx = NewInnerEx()
	}

	return this.StatusEx.ReloadConf(conf)
}
